package com.migu.rbac.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.migu.rbac.model.SysBackApi;
import com.migu.rbac.model.SysMenu;
import com.migu.rbac.repository.SysMenuBackApiRepository;
import com.migu.rbac.repository.SysMenuRepository;
import com.migu.rbac.vo.MenuRVo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Description TODO :
 * @Author: zj
 * @Date: 15:03 2019/3/14
 * @Version 1.0
 **/
@Service
@Transactional
public class SysMenuService {

    private static Logger log = LoggerFactory.getLogger(SysMenuService.class);
    @Autowired
    private SysMenuRepository menuRepository;

    @Autowired
    SysMenuBackApiRepository menuBackApiRepository;

    @Autowired
    SysBackApiService sysBackApiService;

    @Autowired
    SysMenuBackApiService saveMenuApi;


    //根据角色id查询出该角色下所有的菜单
    public List<SysMenu> getMenu(String userId) {
        List<SysMenu> menuList = menuRepository.selectMenuByUserId(userId);
        List<SysMenu> sysMenus = new ArrayList<>();
        for (SysMenu sysMenu : menuList) {
            SysMenu child = sysMenu;
            if (child.getParentid() == null) {
                //获取顶级节点
                sysMenus.add(child);
            } else {
                for (SysMenu menu : menuList) {
                    if (menu.getParentid().equals(child.getId())) {
                        //父节点
                        SysMenu parent = menu;
                        //组合父子关系
                        parent.getMenuList().add(child);
                        break;
                    }
                }
            }
        }
        return sysMenus;
    }

    //根据角色id查询出该角色下所有的菜单
    public List<SysMenu> getMenuMap(String rid) {
        List<SysMenu> menuList = menuRepository.selectMenuByUserId(rid);
        return getMenuTree(menuList);
    }

    //查询所有菜单
    public List<SysMenu> findAllMenuList() {
        List<SysMenu> allMenuList = menuRepository.findAllMenuList();
        return getMenuTree(allMenuList);
    }

    //获取菜单位置
    private int getMenuPosition(SysMenu sysMenu) {
        //获取菜单下最大值
        Integer posList = menuRepository.getMenuPosition(sysMenu);
        if (posList == null) {
            return 1;
        } else {
            return posList + 1;
        }
    }

    //新增菜单
    public Boolean savaMenu(SysMenu sysMenu) {
        if (menuRepository.selectMenuIsExists(sysMenu) > 0) {
            return false;
        }
        //设置位置
        sysMenu.setPosition(getMenuPosition(sysMenu));
        if (menuRepository.savaMenu(sysMenu) > 0) {
            //新增到api表
            int menuid = menuRepository.selectMenuIdByMenuName(sysMenu.getMenuname(), sysMenu.getParentid());
            if (!addMenuApi(sysMenu, menuid)) {
                throw new RuntimeException("api已经存在，不能重复添加");
            }
            return true;
        } else {
            return false;
        }
    }

    public Boolean addMenuApi(SysMenu sysMenu, int menuid) {
        try {
            if (sysMenu.getApilist() != null && !sysMenu.getApilist().isEmpty()) {
                //SysMenu oneWithRolesById = findOneWithRolesById(menuid);
                List<SysBackApi> sysBackApi = getSysBackApi(sysMenu.getApilist());
                Integer[] apis = new Integer[sysBackApi.size()];
                int c = 0;
                for (SysBackApi e : sysBackApi) {
                    if (sysBackApiService.save(e)) {
                        //查询url所需权限保存到缓存
                        // redisUtil.set(RedisCahceConstant.URLPATHMETHOD_FIRST+ e.getPath() + e.getMethod(), oneWithRolesById.getRoles());
                        Integer id = sysBackApiService.selectIDByPathAndMethod(e.getPath(), e.getMethod());
                        e.setId(id);
                        apis[c] = id;
                        c++;
                    } else {
                        return false;
                    }
                }
                //新增到api_menu
                saveMenuApi.saveMenuApi(menuid, apis);
            }
        } catch (Exception e) {
            log.info(e.getMessage());
            return false;
        }
        return true;
    }

    //转为json
    public String toJsonBack(List<SysBackApi> sysBackApis) {
        String s = JSON.toJSONString(sysBackApis);
        return s;
    }

    public List<SysBackApi> getSysBackApi(String apilist) {
        List<SysBackApi> sysBackApis = JSONArray.parseArray(apilist, SysBackApi.class);
        return sysBackApis;
    }


    //删除菜单
    public Boolean deleteMenu(int menuid) {
        if (menuRepository.deleteMenu(menuid) > 0) {
            //删除
            menuRepository.deleteChildMenu(menuid);
            //删除api
            sysBackApiService.deleteBackApiByMenuId(menuid);
            //删除菜单对应path
            menuBackApiRepository.deleteMenuApiBymenuId(menuid);
            //删除缓存
            //redisUtil.delKeys(RedisCahceConstant.URLPATHMETHOD_FIRST  );
            return true;
        } else {
            return false;
        }
    }

    //编辑菜单
    public Boolean updateMenu(SysMenu sysMenu) {
        //修改前看是否有同名菜单
        if (menuRepository.selectMenuNameByUpdate(sysMenu) > 0) {
            return false;
        }
        if (menuRepository.updateMenu(sysMenu) > 0) {
            //修改api
            //int menuid = menuRepository.selectMenuIdByMenuName(sysMenu.getMenuname(), sysMenu.getParentid());
            int menuid = sysMenu.getId();
            //删除和修改都是 新增操作
            //删除api表
            sysBackApiService.deleteBackApiByMenuId(menuid);
            //删除菜单对应api
            menuBackApiRepository.deleteMenuApiBymenuId(menuid);
            //删除缓存
            //  redisUtil.delKeys(RedisCahceConstant.URLPATHMETHOD_FIRST  );
            //新增
            if (!addMenuApi(sysMenu, menuid)) {
                //事务
                throw new RuntimeException("api已经存在，不能重复添加");
            }
            return true;
        } else {
            return false;
        }
    }

    //组装菜单树
    public List<SysMenu> getMenuTree(List<SysMenu> menuList) {
        if (menuList.size() == 0) {
            return menuList;
        }
        List<SysMenu> sysMenus = new ArrayList<>();
        Map<Integer, SysMenu> permissionMap = new HashMap<Integer, SysMenu>();
        for (SysMenu menu : menuList) {
            permissionMap.put(menu.getId(), menu);
        }
        for (SysMenu menu : menuList) {
            SysMenu child = menu;
            if (child.getParentid().equals("1000")) {
                sysMenus.add(menu);
            } else {
                SysMenu parent = permissionMap.get(Integer.parseInt(child.getParentid()));
                parent.getMenuList().add(child);
            }
        }
        sysMenus.get(0).sortChildren();
        return sysMenus;
    }

    //根据菜单id查询该菜单需要什么角色
    public SysMenu findOneWithRolesById(Integer id) {
        return menuRepository.findOneWithRolesById(id);
    }

    //移动菜单
    public Boolean moveMenu(MenuRVo vo) {
        //自己的换成别人的
        try {
            SysMenu selfMenu = new SysMenu();
            selfMenu.setId(vo.getSelfId());
            selfMenu.setPosition(vo.getSidePosition());
            //交换位置
            menuRepository.moveMenuPosition(selfMenu);
            //别人的换成自己的
            SysMenu sideMenu = new SysMenu();
            sideMenu.setId(vo.getSideId());
            sideMenu.setPosition(vo.getSelfPosition());
            menuRepository.moveMenuPosition(sideMenu);
        } catch (Exception e) {
            throw e;
        }
        return true;
    }


}
